package com.logic.system.service.impl;

import java.io.UnsupportedEncodingException;

import javax.xml.bind.JAXBException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import com.logic.common.exception.BusinessException;
import com.logic.common.ws.dto.system.TaskDTO;
import com.logic.system.remote.WriteBackStatusClient;
import com.logic.system.service.ITaskService;
import com.logic.system.service.IWritebackStatusService;
import com.logic.system.wsdl.NotifyResponse;
import com.logic.system.wsdl.model.ResponseRet;
import com.logic.system.wsdl.utils.WritebackStatusCreator;

/**
 * Author: omer 
 * Date  : 07-03-2016
 */
@Component
public class WritebackStatusService implements IWritebackStatusService, ApplicationContextAware {

    private ApplicationContext applicationContext;
    @Autowired
    private WriteBackStatusClient writeBackStatusClient;

    private ITaskService taskService;

    @Autowired
    private LogService logService;
    
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    //@Async
    public void sendWriteBackStatusNotifyIfNecessary(TaskDTO taskDTO, String ipAddress, Integer creator) throws JAXBException, UnsupportedEncodingException, BusinessException {
        logService.info(this.getClass(), ipAddress,
                creator,
                "=== Start to write back the status for task: " + taskDTO.toString(),
                "WBS");
        try {
            String xmlData = WritebackStatusCreator.getInstance().generateWritebackStatusData(taskDTO);
            //logger.info("XML DATA : \n" + xmlData);
            logService.info(this.getClass(),  ipAddress, creator, xmlData, "WBS-XML");

            NotifyResponse response = writeBackStatusClient.notify(xmlData);

            String responseString  = response.getReturn().getValue();

            //logger.info("Write back status response from toshiba : " + responseString);
            logService.info(this.getClass(),  ipAddress, creator, "Write back status response from toshiba : " + responseString, "WBS");

            ResponseRet responseObject = WritebackStatusCreator.getInstance().unmarshallResponse(responseString);

            //logger.info("Write back status response unmarshall : " + responseObject);
            logService.info(this.getClass(), ipAddress, creator, "Write back status response unmarshall : " + responseObject, "WBS");




            // TODO : update the writeback status according to the response
            getTaskService().updateWritebackStatus(String.valueOf(taskDTO.getId()), taskDTO.getTask_type(), "1");


        } catch (JAXBException | UnsupportedEncodingException e){
            StackTraceElement[] trace = e.getStackTrace();
            StringBuilder sb = new StringBuilder();
            for (StackTraceElement traceElement : trace){
                sb.append(traceElement.getClassName())
                        .append(".").append(traceElement.getMethodName())
                        .append("#[").append(traceElement.getLineNumber()).append("]");
            }
            logService.error(this.getClass(), ipAddress,
                    creator,
                    "Message :" + e.getMessage() + "  |  Trace : " +  sb.toString(),
                    "WBS");
            throw e;
        } catch (Exception e) {
            logger.error("sendWriteBackStatusNotifyIfNecessary error.", e);
            StackTraceElement[] trace = e.getStackTrace();
            StringBuilder sb = new StringBuilder();
            for (StackTraceElement traceElement : trace){
                sb.append(traceElement.getClassName())
                        .append(".").append(traceElement.getMethodName())
                        .append("#[").append(traceElement.getLineNumber()).append("]");
            }
            logService.error(this.getClass(), ipAddress,
                    creator,
                    "Message :" + e.getMessage() + "  |  Trace : " +  sb.toString(),
                    "WBS");
        } finally {
        	logService.info(this.getClass(), ipAddress,
                    creator,
                    "=== End to write back the status for task: " + taskDTO.toString(),
                    "WBS");
		}
    }

    private ITaskService getTaskService(){
        if (taskService == null){
            this.taskService = (ITaskService)this.applicationContext.getBean("taskService");
        }

        return this.taskService;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
